/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.editor;

import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.PaletteSeparator;
import org.eclipse.gef.palette.PaletteStack;
import org.eclipse.gef.palette.ToolEntry;

import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.extensionpoints.palette.Button;
import com.cea.papyrus.core.extensionpoints.palette.MenuElement;
import com.cea.papyrus.core.extensionpoints.palette.RegisteredMenu;
import com.cea.papyrus.core.extensionpoints.palette.Separator;
import com.cea.papyrus.core.extensionpoints.palette.Stack;
import com.cea.papyrus.core.utils.Debug;

/**
 * Utility class that can create a GEF Palette.
 * 
 * @see #createPalette()
 * @author Patrick Tessier
 */
public final class DiagramPalette extends PaletteRoot {

	/** Type of Diagram that owns this palette */
	private String typeDiagram;
	
	/** Debug channel */
	private static final int channel = 23;
	
	/**
	 * Constructor.
	 * 
	 * @param type 
	 */
	public DiagramPalette(String type) {
		super();	
		this.typeDiagram = type;
	}
	
	/**
	 * Parse PaletteMenu extension points and creates correspinding
	 * menus in current palette.
	 */
	public void createMenuExtensions() {
		RegisteredMenu[] menus = RegisteredMenu.getRegisteredMenus();
		
		if (menus == null) {
			return;
		}
		
		for (int i = 0; i < menus.length; i++) {
			RegisteredMenu currentMenu = menus[i];
			
			if (currentMenu.isVisibleInDiagram(typeDiagram)) {
				createMenu(currentMenu);
			}
		}
	}
	
	/**
	 * Create a new Drawer that contains a menu defined
	 * as an extension point (PaletteMenu).
	 * 
	 * @param menu 
	 */
	public void createMenu(RegisteredMenu menu) {
		RegisteredMenu[] menus = RegisteredMenu.getRegisteredMenus();
		
		if (menus == null) {
			return;
		}
		
		PaletteDrawer menuDrawer = new PaletteDrawer(menu.getLabel());
		add(menuDrawer);

		// Parsing elements
		MenuElement[] elements = menu.getMenuElements();
		if (elements == null) {
			return;
		}
		
		for (int i = 0; i < elements.length; i++) {
			MenuElement currentMenuElement = elements[i];
			
			if (currentMenuElement instanceof Button) {
				createMenuElement((Button) currentMenuElement, null, menuDrawer);
				
			} else if (currentMenuElement instanceof Stack) {
				createMenuElement((Stack) currentMenuElement, menuDrawer);				
				
			} else if (currentMenuElement instanceof Separator) {
				menuDrawer.add(new PaletteSeparator());
				
			} else {
				Debug.error(this, "DiagramPalette::createMenu() : unknown element.", channel);
			}
		}
	}
	
	/**
	 * Add a new button in palette or paletteStack built on the
	 * basis of button defined in a PaletteMenu extension point.
	 * 
	 * @param drawer 
	 * @param containerStack 
	 * @param button 
	 */
	public void createMenuElement(Button button, PaletteStack containerStack, PaletteDrawer drawer) {
		if (button == null) {
			return;
		}
		
		ToolEntry buttonComponent;
		if (button.getGraphType().equals("EDGE")) {
			// Edge creation
			buttonComponent
				= PapyrusPlugin.creationToolFactory.getEdgeCreationEntry(button);
			
		} else {
			// Node creation
			buttonComponent
				= PapyrusPlugin.creationToolFactory.getNodeCreationEntry(button);
		}

		
		if (containerStack != null) {
			containerStack.add(buttonComponent);
		} else {
			drawer.add(buttonComponent);
		}
	}
	
	/**
	 * Creates a new Stack (from PaletteMenu extension point)
	 * into current palette.
	 * 
	 * @param drawer 
	 * @param stack 
	 */
	public void createMenuElement(Stack stack, PaletteDrawer drawer) {

		if ((stack == null) || (drawer == null)) {
			return;
		}

		// Create stack
		PaletteStack paletteStack = new PaletteStack("", "", null);
		drawer.add(paletteStack);

		// Add buttons
		Button[] buttons = stack.getButtons();
		if (buttons == null) {
			return;
		}

		for (int i = 0; i < buttons.length; i++) {
			Button currentButton = buttons[i];
			createMenuElement(currentButton, paletteStack, null);
		}
	}
	
	/**
	 * 
	 */
	public void refreshMenuExtensions() {
		
	}

	/**
	 * 
	 * 
	 * @return 
	 */
	public String getTypeDiagram() {
		return typeDiagram;
	}
}